package com.english.websocket;


import com.english.sign.Hmac256Signature;
import com.english.util.AuthUtil;
import com.english.websocket.dealer.SendTask;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

import java.net.MalformedURLException;
import java.security.SignatureException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AppClient {
    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();

    private String hostUrl;
    private final String apiKey;
    private final String apiSecret;

    private Request request;
    private final OkHttpClient okHttpClient;
    private WebSocket webSocket;

    public AppClient(String apiKey, String apiSecret, String hostUrl) {
        this.okHttpClient = (new OkHttpClient()).newBuilder().build();
        this.apiKey = apiKey;
        this.apiSecret = apiSecret;
        this.hostUrl = hostUrl;
    }

    public void connectWSAndStartTask(WebSocketListener webSocketListener) throws MalformedURLException, SignatureException {
        this.createWebSocketConnect(webSocketListener);
        SendTask sendTask = new SendTask();
        sendTask.setAppClient(this);
        executorService.submit(sendTask);
    }

    private void createWebSocketConnect(WebSocketListener webSocketListener) throws MalformedURLException, SignatureException {
        this.hostUrl = this.hostUrl.replace( "ws://", "http://").replace( "wss://", "https://");
        Hmac256Signature signature = new Hmac256Signature(this.apiKey, this.apiSecret, this.hostUrl);
        this.hostUrl = AuthUtil.generateRequestUrl(signature);
        this.request = (new Request.Builder()).url(this.hostUrl).build();
        this.newWebSocket(webSocketListener);
    }

    private void newWebSocket(WebSocketListener listener) {
        this.webSocket = this.okHttpClient.newWebSocket(this.request, listener);
    }

    public WebSocket getWebSocket() {
        return this.webSocket;
    }

    public void closeWebsocket() {
        if (this.webSocket != null) {
            this.webSocket.close(1000, null);
            this.okHttpClient.connectionPool().evictAll();
        }
    }

}
